home *** CD-ROM | disk | FTP | other *** search
/ Mac Cube 4: Multimedia Applications / MacCube Volume 4: Multimedia Applications.iso / Graphics / POV Ray / POVSOURCE / SOURCE / Animate.c next >
Text File  |  1993-11-30  |  10KB  |  338 lines

  1. /*==============================================================================
  2. Project:    POV
  3.  
  4. File:    Animate.c
  5.  
  6. Description:
  7. Routines to handle the clock animation variable prompting for POV-Ray.
  8. ------------------------------------------------------------------------------
  9. Author:
  10.     Eduard [esp] Schwan
  11. ------------------------------------------------------------------------------
  12.     from Persistence of Vision Raytracer
  13.     Copyright 1993 Persistence of Vision Team
  14. ------------------------------------------------------------------------------
  15.     NOTICE: This source code file is provided so that users may experiment
  16.     with enhancements to POV-Ray and to port the software to platforms other 
  17.     than those supported by the POV-Ray Team.  There are strict rules under
  18.     which you are permitted to use this file.  The rules are in the file
  19.     named POVLEGAL.DOC which should be distributed with this file. If 
  20.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  21.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  22.     Forum.  The latest version of POV-Ray may be found there as well.
  23.  
  24.     This program is based on the popular DKB raytracer version 2.12.
  25.     DKBTrace was originally written by David K. Buck.
  26.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  27. ------------------------------------------------------------------------------
  28. More Info:
  29.     This Macintosh version of POV-Ray was created and compiled by Jim Nitchals
  30.     (Think 5.0) and Eduard Schwan (MPW 3.2), based (loosely) on the original
  31.     port by Thomas Okken and David Lichtman, with some help from Glenn Sugden.
  32.  
  33.     For bug reports regarding the Macintosh version, you should contact:
  34.     Eduard [esp] Schwan
  35.         CompuServe: 71513,2161
  36.         Internet: jl.tech@applelink.apple.com
  37.         AppleLink: jl.tech
  38.     Jim Nitchals
  39.         Compuserve: 73117,3020
  40.         America Online: JIMN8
  41.         Internet: jimn8@aol.com -or- jimn8@applelink.apple.com
  42.         AppleLink: JIMN8
  43. ------------------------------------------------------------------------------
  44. Change History:
  45.     930226    [esp]    Created
  46.     930605    [esp]    Changed initial frame # from zero to one
  47.     930707    [esp]    Checked for frame 1 to 1, avoid div by zero
  48.     930708    [esp]    Changed clock value display from 3 to 5 digits
  49.     930728    [esp]    Added frameValS/frameValE
  50.     930816    [esp]    Added pAnimPtr to SetCurrFrameVal & made it set curr clock val too
  51.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  52.     931119    [djh]    2.0.1 source conditionally compiles for PPC machines, keyword __powerc
  53. ==============================================================================*/
  54.  
  55. #define ANIMATE_C
  56.  
  57. /*==== POV-Ray std headers ====*/
  58. #include "POVMac.h"    // setupdefaultbutton
  59.  
  60.  
  61. /*==== Standard C headers ====*/
  62. #include <stdlib.h>        // malloc
  63.  
  64.  
  65. /*==== Macintosh-specific headers ====*/
  66. // NOTE: _H_MacHeaders_ is defined by Think C if it is using
  67. // precompiled headers.  This is only for compilation speed improvement.
  68. #if !defined(_H_MacHeaders_)
  69. #include <types.h>
  70. #include <memory.h>        // NewPtr
  71. #endif // _H_MacHeaders_
  72.  
  73. #if !defined (THINK_C)
  74. #include <strings.h>
  75. #endif // THINK_C
  76.  
  77.  
  78. /*==== Animate header ====*/
  79. #include "Animate.h"
  80.  
  81.  
  82. /*==== defs ====*/
  83.  
  84. // dialog constants
  85. #define Dlog_ID                    156
  86. #define    Ditem_ST_FrameVal0        4
  87. #define    Ditem_ET_FrameValS        5
  88. #define    Ditem_ET_FrameValE        6
  89. #define    Ditem_ET_FrameValN        7
  90. #define    Ditem_ET_Clock0Val        8
  91. #define    Ditem_ST_ClockValS        9
  92. #define    Ditem_ST_ClockValE        10
  93. #define    Ditem_ET_ClockNVal        11
  94. #define    Ditem_MAX                Ditem_ET_ClockNVal
  95.  
  96.  
  97. /*==== vars ====*/
  98.  
  99. static short    gCurrFrameVal;
  100. static float    gCurrentClockVal;
  101.  
  102.  
  103. //-----------------------------------------------------------
  104. // Calculate a clock value based on currFrameVal, etc.
  105. static float CalcClockVal(AnimPtr_t pAnimPtr, short currFrameVal)
  106. {
  107.     DBL        tCurrClockVal;
  108.  
  109.     // THE MOST USEFUL CALCULATION IN THE WORLD! :-)
  110.     // if frames are related to clocks, and frame is this, what's clock?
  111.     if (currFrameVal == 1)
  112.     {
  113.         // If Frame(1), just return clock(0), so we don't divide by zero!
  114.         tCurrClockVal = pAnimPtr->clockVal0;
  115.     }
  116.     else
  117.     {
  118.         // do the real calculation
  119.         tCurrClockVal = pAnimPtr->clockVal0
  120.             + (    (DBL)currFrameVal        - (DBL)pAnimPtr->frameVal0    )
  121.             * (    (DBL)pAnimPtr->clockValN - pAnimPtr->clockVal0        )
  122.             / (    (DBL)pAnimPtr->frameValN - (DBL)pAnimPtr->frameVal0    );
  123.     }
  124.  
  125.     return tCurrClockVal;
  126.  
  127. } // CalcClockVal
  128.  
  129.  
  130. //-----------------------------------------------------------
  131. // Set local current frame value (and calculate current clock value too)
  132. void SetCurrFrameVal(AnimPtr_t pAnimPtr, short newFrameVal)
  133. {
  134.     gCurrFrameVal        = newFrameVal;
  135.     gCurrentClockVal    = CalcClockVal(pAnimPtr, newFrameVal); // calc. curr clock
  136. } // SetCurrFrameVal
  137.  
  138.  
  139. //-----------------------------------------------------------
  140. // Return local current frame value
  141. short GetCurrFrameVal(void)
  142. {
  143.     return gCurrFrameVal;
  144. } // GetCurrFrameVal
  145.  
  146.  
  147. //-----------------------------------------------------------
  148. // Return local current clock value
  149. float GetCurrClockVal(void)
  150. {
  151.     return gCurrentClockVal;
  152. } // GetCurrClockVal
  153.  
  154.  
  155. //-----------------------------------------------------------
  156. // Increment Frame counter if not already finished, and recalculate
  157. // new clock value.  Return true if already at last frame
  158. Boolean IncToNextFrame(AnimPtr_t pAnimPtr)
  159. {
  160.     Boolean    nextFrameOK = false;
  161.     short    frameVal;
  162.  
  163.     frameVal = GetCurrFrameVal();
  164.  
  165.     // before last frame?
  166.     if (frameVal < pAnimPtr->frameValE)
  167.     {    // go to next frame
  168.         frameVal++; // go to next
  169.         SetCurrFrameVal(pAnimPtr, frameVal); // save it & calc curr clock val
  170.         nextFrameOK = true;
  171.     }
  172.  
  173.     return nextFrameOK;
  174. } // IncToNextFrame
  175.  
  176.  
  177. //-----------------------------------------------------------
  178. // Put up dialog of options, and return TRUE if user clicks ok, else FALSE if cancel
  179. Boolean GetAnimateOptions(AnimPtr_t pAnimPtr)
  180. {
  181.     short            itemHit, prevItemHit;
  182.     DialogPtr        myDialog;
  183.     short            k, dummy;
  184.     float            clockValS, clockValE;
  185.     AnimRec_t        tAnimRec;
  186.     Rect            displayRect;
  187.     ControlHandle    theDItems[Ditem_MAX+1];
  188.     char            aString[32];
  189.  
  190.     myDialog = GetNewDialog(Dlog_ID, NULL, (WindowPtr)-1);
  191.  
  192.     for (k = 1; k<=Ditem_MAX; k++)
  193.         GetDItem(myDialog, k, &dummy, (Handle *) &theDItems[k], &displayRect);
  194.  
  195.     tAnimRec = *pAnimPtr;    // start off with what they passed us
  196.  
  197.     // select something..
  198.     SelIText(myDialog, Ditem_ET_FrameValS, 0, -1);
  199.  
  200.     PositionWindow(myDialog, ewcDoCentering, eSameAsPassedWindow, (WindowPtr)gp2wWindow);
  201.  
  202.     // "default" the OK button
  203.     SetupDefaultButton(myDialog);
  204.  
  205.     SetCursor(&qd.arrow);
  206.     ShowWindow(myDialog);
  207.  
  208.     // prompt until user clicks ok or cancel
  209.     prevItemHit = itemHit = -1;
  210.     do
  211.     {
  212.         // Initial Frame
  213.         sprintf(aString, "%d", tAnimRec.frameVal0); // always starts at frame 1
  214.         c2pstr(aString);
  215.         SetIText((Handle)theDItems[Ditem_ST_FrameVal0], (StringPtr)aString);
  216.  
  217.         // Start Frame
  218.         sprintf(aString, "%d", tAnimRec.frameValS);
  219.         c2pstr(aString);
  220.         SetIText((Handle) theDItems[Ditem_ET_FrameValS], (StringPtr)aString);
  221.  
  222.         // End Frame
  223.         sprintf(aString, "%d", tAnimRec.frameValE);
  224.         c2pstr(aString);
  225.         SetIText((Handle) theDItems[Ditem_ET_FrameValE], (StringPtr)aString);
  226.  
  227.         // Final Frame
  228.         sprintf(aString, "%d", tAnimRec.frameValN);
  229.         c2pstr(aString);
  230.         SetIText((Handle) theDItems[Ditem_ET_FrameValN], (StringPtr)aString);
  231.  
  232.         // Initial Clock
  233.         sprintf(aString, "%.5f", tAnimRec.clockVal0);
  234.         c2pstr(aString);
  235.         SetIText((Handle) theDItems[Ditem_ET_Clock0Val], (StringPtr)aString);
  236.  
  237.         // Start Clock
  238.         clockValS = CalcClockVal(&tAnimRec, tAnimRec.frameValS);
  239.         sprintf(aString, "%.5f", clockValS);
  240.         c2pstr(aString);
  241.         SetIText((Handle) theDItems[Ditem_ST_ClockValS], (StringPtr)aString);
  242.  
  243.         // End Clock
  244.         clockValE = CalcClockVal(&tAnimRec, tAnimRec.frameValE);
  245.         sprintf(aString, "%.5f", clockValE);
  246.         c2pstr(aString);
  247.         SetIText((Handle) theDItems[Ditem_ST_ClockValE], (StringPtr)aString);
  248.  
  249.         // Final Clock
  250.         sprintf(aString, "%.5f", tAnimRec.clockValN);
  251.         c2pstr(aString);
  252.         SetIText((Handle) theDItems[Ditem_ET_ClockNVal], (StringPtr)aString);
  253.  
  254.         // don't exit & re-validate until they exit a field
  255.         do {
  256.             prevItemHit = itemHit;
  257.             ModalDialog(NULL, &itemHit);
  258.         } while ((prevItemHit == itemHit) && (itemHit != ok) && (itemHit != cancel));
  259.  
  260.         if (itemHit != cancel)
  261.         {
  262.             // Initial Frame = 1 (n/a)
  263.  
  264.             // Final Frame
  265.             GetIText((Handle) theDItems[Ditem_ET_FrameValN], (StringPtr)aString);
  266.             p2cstr((StringPtr)aString);
  267.             if (strlen(aString) == 0)
  268.                 tAnimRec.frameValN = tAnimRec.frameVal0;
  269.             else
  270.                 tAnimRec.frameValN = atoi(aString);
  271.             if (tAnimRec.frameValN < tAnimRec.frameVal0)
  272.                 tAnimRec.frameValN = tAnimRec.frameVal0;
  273.  
  274.             // Start Frame
  275.             GetIText((Handle) theDItems[Ditem_ET_FrameValS], (StringPtr)aString);
  276.             p2cstr((StringPtr)aString);
  277.             if (strlen(aString) == 0)
  278.                 tAnimRec.frameValS = tAnimRec.frameVal0;
  279.             else
  280.                 tAnimRec.frameValS = atoi(aString);
  281.             if ((tAnimRec.frameValS < tAnimRec.frameVal0)
  282.             || (tAnimRec.frameValS > tAnimRec.frameValN))
  283.                 tAnimRec.frameValS = tAnimRec.frameVal0;
  284.  
  285.             // End Frame
  286.             GetIText((Handle) theDItems[Ditem_ET_FrameValE], (StringPtr)aString);
  287.             p2cstr((StringPtr)aString);
  288.             if (strlen(aString) == 0)
  289.                 tAnimRec.frameValE = tAnimRec.frameValN;
  290.             else
  291.                 tAnimRec.frameValE = atoi(aString);
  292.             if ((tAnimRec.frameValE < tAnimRec.frameVal0)
  293.             || (tAnimRec.frameValE > tAnimRec.frameValN))
  294.                 tAnimRec.frameValE = tAnimRec.frameValN;
  295.  
  296.             // Do Start & End Frame overlap?
  297.             if (tAnimRec.frameValE < tAnimRec.frameValS)
  298.                 tAnimRec.frameValE = tAnimRec.frameValS;
  299.             
  300.  
  301.             // Initial Clock Val
  302.             GetIText((Handle) theDItems[Ditem_ET_Clock0Val], (StringPtr)aString);
  303.             p2cstr((StringPtr)aString);
  304.             if (strlen(aString) == 0)
  305.                 tAnimRec.clockVal0 = 0.0;
  306.             else
  307.                 tAnimRec.clockVal0 = atof(aString);
  308.  
  309.             // Final Clock Val
  310.             GetIText((Handle) theDItems[Ditem_ET_ClockNVal], (StringPtr)aString);
  311.             p2cstr((StringPtr)aString);
  312.             if (strlen(aString) == 0)
  313.                 tAnimRec.clockValN = 1.0;
  314.             else
  315.                 tAnimRec.clockValN = atof(aString);
  316.  
  317.             // Final & Initial clock are too close, change Final
  318.             if (fabs(tAnimRec.clockValN-tAnimRec.clockVal0) < 1.0e-10)
  319.             {
  320.                 tAnimRec.clockValN = tAnimRec.clockVal0 + 1.0;
  321.                 SysBeep(4);
  322.             }
  323.         }
  324.     } while (itemHit != ok && itemHit != cancel);
  325.  
  326.     if (itemHit == ok)
  327.     {
  328.         // return it
  329.         *pAnimPtr = tAnimRec;
  330.     }
  331.  
  332.     DisposeDialog(myDialog);
  333.  
  334.     // return TRUE if user hit OK
  335.     return (itemHit == ok);
  336.  
  337. } // GetAnimateOptions
  338.